/*
 *   Copyright 2011-2012 Hai Bison
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
package group.pals.mailgate.threads;

import group.pals.TinyTextImage.BinaryImage;
import group.pals.threads.BaseThread;
import group.pals.threads.listeners.ThreadListener;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;

/**
 *
 * @author Hai Bison
 */
public class BinImageFileDecoder extends BaseThread {

    public static final int KeyDecodingProgress = 0;
    private final File BinImageFile;
    private final String Signature;
    private final long BinImageFileSize;
    private long decodedSize = 0;
    private long lastTick = 0;

    public BinImageFileDecoder(File binImageFile, String signature) {
        super(null);
        this.BinImageFile = binImageFile;
        this.Signature = signature;
        this.BinImageFileSize = binImageFile.length();
    }

    @Override
    public void run() {
        notifyStarted();

        BinaryImage bi = null;
        try {
            bi = new BinaryImage(Signature, BinImageFile);

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            try {
                while (true) {
                    waitWhileSuspending();
                    if (isInterrupted()) {
                        break;
                    }

                    byte[] buf = bi.read();
                    if (buf != null) {
                        baos.write(buf);
                        decodedSize += buf.length;
                        notifyDecodingProgress();
                    } else {
                        break;
                    }
                }
                bi.close();

                notifyDecodingProgress();
                FileOutputStream fos = new FileOutputStream(BinImageFile);
                try {
                    fos.write(baos.toByteArray());
                } finally {
                    fos.close();
                }
            } finally {
                baos.close();
            }
        } catch (Exception ex) {
            notifyException(ex);
        } finally {
            if (bi != null) {
                bi.close();
            }
        }

        notifyTerminated();
    }

    /*----------------------------------------------------------------------------
     * Event Notifiers
     */
    private void notifyDecodingProgress() {
        if (System.currentTimeMillis() - lastTick > 999) {
            for (ThreadListener listener : Listeners) {
                listener.threadSignaled(Instance, KeyDecodingProgress, decodedSize);
            }
            lastTick = System.currentTimeMillis();
        }
    }

    /**
     * @return the BinImageFileSize
     */
    public long getBinImageFileSize() {
        return BinImageFileSize;
    }
}
